<?php

namespace App\Models;

use App\Models\Traits\HotTopicHelper;
use Dcat\Admin\Traits\HasDateTimeFormatter;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Arr;

class Topic extends Model
{
    use HasDateTimeFormatter;
    use SoftDeletes;
    use HasFactory;
    use HotTopicHelper;

    protected $fillable = [
        'title', 'body', 'category_id', 'excerpt', 'slug',
        'publish', 'publish_at',
    ];

    protected $casts = [
        'publish_at' => 'datetime',
    ];

    public function replies()
    {
        return $this->hasMany(Reply::class);
    }

    public function category(): \Illuminate\Database\Eloquent\Relations\BelongsTo
    {
        return $this->belongsTo(Category::class);
    }

    public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    public function reply_user(): \Illuminate\Database\Eloquent\Relations\BelongsTo
    {
        return $this->belongsTo(User::class, 'last_reply_user_id');
    }


    public function scopeWithOrder($query, $order)
    {
        // 不同的排序，使用不同的数据读取逻辑
        switch ($order) {
            case 'recent':
                $query->recent();
                break;

            default:
                $query->recentReplied();
                break;
        }
    }

    public function scopeRecentReplied($query)
    {
        // 当话题有新回复时，我们将编写逻辑来更新话题模型的 reply_count 属性，
        // 此时会自动触发框架对数据模型 updated_at 时间戳的更新
        return $query->orderBy('updated_at', 'desc');
    }

    public function scopeRecent($query)
    {
        // 按照创建时间排序
        return $query->orderBy('created_at', 'desc');
    }

    public function link($params = []): string
    {
        return route('topics.show', array_merge([$this->id, $this->slug], $params));
    }

    public function updateReplyCount()
    {
        $this->reply_count = $this->replies->count();
        $this->save();
    }

    public function tags()
    {
        return $this->belongsToMany(Tag::class, 'topic_tag', 'topic_id', 'tag_id');
    }

    public function hasTag(Tag $tag)
    {
        $tags = Arr::pluck($this->tags, 'id');
        if (count($tags)) {
            return in_array($tag->id, $tags);
        } else {
            return false;
        }
    }

    public function getStrTagsAttribute()
    {
        return implode(',', Arr::pluck($this->tags, 'name', 'id'));
    }

    public function getTagIdsAttribute()
    {
        return Arr::pluck($this->tags, 'id');
    }
}
